package com.huawei.translate.service;

import com.google.gson.Gson;
import com.huawei.translate.model.AccessToken;
import com.huawei.translate.model.DetectRecord;
import com.huawei.translate.model.Renter;
import com.huawei.translate.model.TranslateRecord;
import com.huawei.translate.persistence.RenterRepository;
import com.huawei.translate.provider.TranslateProviderType;
import com.huawei.translate.utils.LogUtil;
import com.huawei.translate.vo.translate.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.List;

@Service
public class TranslateRecordService {

    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private Gson gson = new Gson();

    @Autowired
    private RenterRepository renterRepository;

    @Autowired
    private AuthenticationService authenticationService;

    public void record(TranslateRequest request, TranslateResponse translateResult, String provider, String traceId) {
        if (translateResult != null) {
            success(request, request.getText(), translateResult.getMessage(), provider, traceId);
        } else {
            failed(request, request.getText(), "", provider, traceId);
        }
    }

    public void record(TranslateArrayRequest request, List<String> translateResult, String provider, String traceId) {
        if (translateResult != null) {
            success(request, StringUtils.join(request.getTexts(), ','), StringUtils.join(translateResult, ','), provider, traceId);
        } else {
            failed(request, StringUtils.join(request.getTexts(), ','), "", provider, traceId);
        }
    }

    public void failed(TranslateBaseRequest request, String sourceText, String translateResult, String provider, String traceId) {
        log(createRecord(request, sourceText, translateResult, provider, traceId, false));
    }

    public void success(TranslateBaseRequest request, String sourceText, String translateResult, String provider, String traceId) {
        log(createRecord(request, sourceText, translateResult, provider, traceId, true));
    }

    public TranslateRecord createRecord(TranslateBaseRequest request, String sourceText, String translateResult, String provider, String traceId, boolean success) {
        TranslateRecord record = new TranslateRecord();
        AccessToken token = authenticationService.parseAccessToken(request.getAccessToken());
        Renter renter = renterRepository.findByAppSecret(token.getAppSecret());
        record.setTenantId(renter.getAppKey());
        record.setSourceText(sourceText);
        record.setTraceId(traceId);
        record.setProvider(provider);

        if (renter.getCategory() != null) {
            record.setCategory(renter.getCategory());
        } else {
            record.setCategory("");
        }
        record.setSuccess(success);
        record.setTranslateResult(translateResult);
        record.setDataTime(format.format(System.currentTimeMillis()));
        record.setTimeStamp(System.currentTimeMillis());
        record.setFrom(request.getFrom());
        record.setTo(request.getTo());
        return record;
    }

    public void log(Object record) {
        LogUtil.info(gson.toJson(record));
    }

    public void recordDetect(DetectRequest detectRequest, String languages) {
        log(createRecord(detectRequest, languages));
    }

    public DetectRecord createRecord(DetectRequest detectRequest, String language) {
        Renter renter = authenticationService.parseRenterFromAccessToken(detectRequest.getAccessToken());

        DetectRecord detectRecord = new DetectRecord();
        detectRecord.setProvider(TranslateProviderType.MS.getDescription());
        detectRecord.setSourceText(detectRequest.getContent());
        detectRecord.setTenantId(renter.getAppKey());
        detectRecord.setTimeStamp(System.currentTimeMillis());
        detectRecord.setDataTime(format.format(System.currentTimeMillis()));
        if (language == null) {
            detectRecord.setSuccess(false);
            detectRecord.setLanguageCode("");
        } else {
            detectRecord.setSuccess(true);
            detectRecord.setLanguageCode(language);
        }
        return detectRecord;
    }
}
